package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.enums.NoticeTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowNoticeTemplateParameterVo;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ResponseResult;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.*;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowNoticeTemplateRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.NoticeRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.common.FlowCommonCodeConstants;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNoticeTemplate;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNoticeTemplateExample;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNoticeTemplateParameter;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNoticeTemplateParameterExample;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.FlowNoticeTemplateDAO;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.FlowNoticeTemplateParameterDAO;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.NoticeTemplateDAO;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.flowable.engine.common.impl.util.CollectionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 通知模板Service
 *
 * @author wuliepeng
 * @date 2019-07-11
 */
@Service
public class FlowNoticeTemplateRepositoryImpl implements FlowNoticeTemplateRepository {

    @Autowired
    private FlowNoticeTemplateDAO flowNoticeTemplateDAO;

    @Autowired
    private FlowNoticeTemplateParameterDAO flowNoticeTemplateParameterDAO;


    @Autowired
    private NoticeTemplateDAO noticeTemplateDAO;

    @Autowired
    private NoticeRepository noticeRepository;

    private final static String SEND_SUCCESS = "Y";

    @Override
    public ResponseResult list(FlowNoticeTemplateQueryVo flowNoticeTemplateQueryVo) {
        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
        if (StringUtils.isNotEmpty(flowNoticeTemplateQueryVo.getSearchText())) {
            String searchText = "%" + flowNoticeTemplateQueryVo.getSearchText() + "%";
            flowNoticeTemplateExample.createCriteria().andNameLike(searchText);
        }
        PageHelper.startPage(flowNoticeTemplateQueryVo.getPageNum(), flowNoticeTemplateQueryVo.getPageSize());
        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);
        PageInfo<FlowNoticeTemplate> pageInfo = new PageInfo<>(flowNoticeTemplates);

        List<FlowNoticeTemplateInfo> flowNoticeTemplateInfos = new ArrayList<>(flowNoticeTemplates.size());
        for (FlowNoticeTemplate flowNoticeTemplate : flowNoticeTemplates) {
            FlowNoticeTemplateInfo flowNoticeTemplateInfo = new FlowNoticeTemplateInfo();
            BeanUtils.copyProperties(flowNoticeTemplate, flowNoticeTemplateInfo);
            flowNoticeTemplateInfo.setTypeName(NoticeTypeEnum.getDescrByCode(flowNoticeTemplate.getType()));
            flowNoticeTemplateInfos.add(flowNoticeTemplateInfo);
        }
        ResponseResult responseResult = ResponseResult.success(flowNoticeTemplateInfos);
        responseResult.setTotalCount((int) pageInfo.getTotal());
        responseResult.setPageNum(flowNoticeTemplateQueryVo.getPageNum());
        responseResult.setPageSize(flowNoticeTemplateQueryVo.getPageSize());
        return responseResult;
    }

    @Override
    public List<FlowNoticeTemplateInfo> listNoticeTemplateInfo(String type) {
        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
        flowNoticeTemplateExample.createCriteria().andTypeEqualTo(type);
        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);
        if (flowNoticeTemplates != null && !flowNoticeTemplates.isEmpty()) {
            List<FlowNoticeTemplateInfo> flowNoticeTemplateInfos = new ArrayList<>(flowNoticeTemplates.size());
            flowNoticeTemplates.forEach(noticeTemplate -> {
                        FlowNoticeTemplateInfo flowNoticeTemplateInfo = new FlowNoticeTemplateInfo();
                        BeanUtils.copyProperties(noticeTemplate, flowNoticeTemplateInfo);
                        flowNoticeTemplateInfo.setTypeName(NoticeTypeEnum.getDescrByCode(noticeTemplate.getType()));
                        flowNoticeTemplateInfos.add(flowNoticeTemplateInfo);
                    }
            );
            return flowNoticeTemplateInfos;
        }
        return null;
    }

    @Override
    public Boolean isTemplateExist(String noticeType) {
        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
        flowNoticeTemplateExample.createCriteria().andTypeEqualTo(noticeType).andStatusEqualTo();
        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);
        if (CollectionUtils.isEmpty(flowNoticeTemplates)) {
            return false;
        }
        return true;
    }
    @Override
    public Boolean isTemplateExist(String noticeType,Long id) {
        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
        flowNoticeTemplateExample.createCriteria().andTypeEqualTo(noticeType).andStatusEqualTo().andIdNotEqualTo(id);
        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);
        if (CollectionUtils.isEmpty(flowNoticeTemplates)) {
            return false;
        }
        return true;
    }

    @Override
    public Long insert(FlowNoticeTemplateAddVo flowNoticeTemplateAddVo) {
        FlowNoticeTemplate flowNoticeTemplate = new FlowNoticeTemplate();
        BeanUtils.copyProperties(flowNoticeTemplateAddVo, flowNoticeTemplate);
        flowNoticeTemplate.setCreateTime(new Date());
        flowNoticeTemplateDAO.insert(flowNoticeTemplate);
        return flowNoticeTemplate.getId();
    }

    @Override
    public Integer update(FlowNoticeTemplateUpdateVo flowNoticeTemplateUpdateVo) {
        FlowNoticeTemplate flowNoticeTemplate = new FlowNoticeTemplate();
        BeanUtils.copyProperties(flowNoticeTemplateUpdateVo, flowNoticeTemplate);
        flowNoticeTemplate.setUpdateTime(new Date());
        return flowNoticeTemplateDAO.updateByPrimaryKey(flowNoticeTemplate);
    }

    @Override
    public Integer delete(FlowNoticeTemplateDeleteVo flowNoticeTemplateDeleteVo) {
        return flowNoticeTemplateDAO.deleteByPrimaryKey(flowNoticeTemplateDeleteVo.getId());
    }

    @Override
    public List<FlowNoticeTemplateParameterVo> listNoticeTemplateParameter(String type) {
        FlowNoticeTemplateParameterExample flowNoticeTemplateParameterExample = new FlowNoticeTemplateParameterExample();
        List<FlowNoticeTemplateParameterVo> collect = flowNoticeTemplateParameterDAO.selectByExample(flowNoticeTemplateParameterExample).stream().map(this::convert).collect(Collectors.toList());
        List<FlowNoticeTemplateParameterVo> flowNoticeTemplateParameterVos=new ArrayList<>();
        for (FlowNoticeTemplateParameterVo flowNoticeTemplateParameterVo:collect){
            if (flowNoticeTemplateParameterVo.getIncludeType().contains(type)){
                flowNoticeTemplateParameterVos.add(flowNoticeTemplateParameterVo);
            }
        }
        return flowNoticeTemplateParameterVos;
    }

    @Override
    public List<Map<String, String>> listNoticeTemplateType() {
//        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
//        flowNoticeTemplateExample.setDistinct(true);
//        flowNoticeTemplateExample.createCriteria().andStatusEqualTo();
//        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);

        Map<String, String> allNoticeType = NoticeTypeEnum.getCodeToDesc();
        List<String> allNoticeTypeKey = new ArrayList<>();
        for (String key : allNoticeType.keySet()) {
            allNoticeTypeKey.add(key);
        }

//        if (CollectionUtils.isNotEmpty(flowNoticeTemplates)) {
//            List<String> existNoticeType = flowNoticeTemplates.stream().map(FlowNoticeTemplate::getType).distinct().collect(Collectors.toList());
//            allNoticeTypeKey.removeAll(existNoticeType);
//        }
        List<Map<String, String>> notExistNoticeType = new ArrayList<>(allNoticeTypeKey.size());
        for (String key : allNoticeTypeKey) {
            Map<String, String> noticeType = new HashMap<>(2);
            noticeType.put("key", key);
            noticeType.put("value", allNoticeType.get(key));
            notExistNoticeType.add(noticeType);
        }
        return notExistNoticeType;
    }

    @Override
    public String reSendNoticeMessage(String ruNoticeChannelId) {
        NoticeInfo noticeInfo = noticeTemplateDAO.getNoticeInfoByRuNoticeChannelId(ruNoticeChannelId);
        return noticeRepository.reSendNoticeMessage(noticeInfo);
    }

    private FlowNoticeTemplateParameterVo convert(FlowNoticeTemplateParameter entity) {
        if (Objects.isNull(entity)) {
            return null;
        }

        FlowNoticeTemplateParameterVo result = new FlowNoticeTemplateParameterVo();
        BeanUtils.copyProperties(entity, result);
        return result;
    }

    @Override
    public ResponseResult detail(FlowNoticeTemplateDetailVo flowNoticeTemplateDetailVo) {
        FlowNoticeTemplate flowNoticeTemplate = flowNoticeTemplateDAO.selectByPrimaryKey(flowNoticeTemplateDetailVo.getId());
        FlowNoticeTemplateInfo flowNoticeTemplateInfo = new FlowNoticeTemplateInfo();
        BeanUtils.copyProperties(flowNoticeTemplate, flowNoticeTemplateInfo);
        flowNoticeTemplateInfo.setTypeName(NoticeTypeEnum.getDescrByCode(flowNoticeTemplate.getType()));
        return ResponseResult.success(flowNoticeTemplateInfo);
    }

    @Override
    public Integer startStatus(FlowNoticeTemplateStatusVo flowNoticeTemplateStatusVo) {
        FlowNoticeTemplate flowNoticeTemplate = new FlowNoticeTemplate();
        BeanUtils.copyProperties(flowNoticeTemplateStatusVo, flowNoticeTemplate);
        flowNoticeTemplate.setUpdateTime(new Date());
        return flowNoticeTemplateDAO.updateByPrimaryKeySelective(flowNoticeTemplate);
    }

    @Override
    public List<FlowNoticeTemplateVo> getTemplateListByType(String type) {
        FlowNoticeTemplateExample flowNoticeTemplateExample = new FlowNoticeTemplateExample();
        flowNoticeTemplateExample.createCriteria().andTypeEqualTo(type).andStatusEqualTo();
        List<FlowNoticeTemplate> flowNoticeTemplates = flowNoticeTemplateDAO.selectByExample(flowNoticeTemplateExample);
        List<FlowNoticeTemplateVo> flowNoticeTemplateVoList=new ArrayList<>();
        for (FlowNoticeTemplate flowNoticeTemplate:flowNoticeTemplates){
            FlowNoticeTemplateVo flowNoticeTemplateVo=new FlowNoticeTemplateVo();
            BeanUtils.copyProperties(flowNoticeTemplate,flowNoticeTemplateVo);
            flowNoticeTemplateVoList.add(flowNoticeTemplateVo);
        }
        return flowNoticeTemplateVoList;
    }

    @Override
    public Integer updateSendStatus(String ruNoticeChannelId) {
        noticeTemplateDAO.updateSendStatus(ruNoticeChannelId, SEND_SUCCESS);
        return 1;
    }
}
